package com.corewillsoft.fireflies.sounds;

import java.io.IOException;
import java.util.Random;

import org.anddev.andengine.audio.music.Music;
import org.anddev.andengine.audio.music.MusicFactory;
import org.anddev.andengine.audio.sound.Sound;
import org.anddev.andengine.audio.sound.SoundFactory;
import org.anddev.andengine.engine.Engine;

import android.content.Context;
import android.content.res.AssetManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;

import com.corewillsoft.fireflies.engine.IConstants;
import com.corewillsoft.fireflies.util.DebugLog;

public class SoundsManager {

	private static final String TAG = "SoundsManager";
	private static SoundsManager soundsManager;

	private float soundVolume = 0.05f;
	private float musicVolume = 0.2f;
	private int previousGeneratedPosition = -1;

	private Engine engine;
	private Random randomGenerator;
	private Context context;

	private Music randomBgMusic;
	private Sound spiritSaved;
	private Sound menuClick;
	private Sound gameCollision;
	private Sound spiritDead;
	private Sound gameOver;
	private Sound gameFinished;
	private Sound levelFinished;

	public static void initInstance(Engine engine, Context context) {
		if (soundsManager == null) {
			soundsManager = new SoundsManager(engine, context);
		}
	}

	public static SoundsManager getInstance() {
		if (soundsManager == null) {
			DebugLog.e("Init SoundsManager with other constructor @initInstance(Engine engine, Context context)");
		}
		return soundsManager;
	}

	private SoundsManager(Engine engine, Context context) {
		this.engine = engine;
		this.context = context;
		this.randomGenerator = new Random();
	}

	public void initSounds() {
		
		if (menuClick == null) {
			menuClick = createSoundFromAsset("menu_click.ogg");
		}

		if (gameCollision == null) {
			gameCollision = createSoundFromAsset("objects_collission.ogg");
		}

		if (spiritSaved == null) {
			spiritSaved = createSoundFromAsset("save_firefly.ogg");
		}

		if (spiritDead == null) {
			spiritDead = createSoundFromAsset("death_of_soul.ogg");
		}

		if (gameOver == null) {
			gameOver = createSoundFromAsset("game_over.ogg");
		}

		if (gameFinished == null) {
			gameFinished = createSoundFromAsset("level_finished.ogg");
		}
		
		if (levelFinished == null) {
			levelFinished = createSoundFromAsset("level_finished.ogg");
		}

		if (randomBgMusic == null) {
			playRandomBgMusic();
		}
	}

	public void releaseAll() {
		soundsManager = null;
	}

	private Music getRandomBgMusic() {
		AssetManager manager = context.getAssets();
		String[] randomMusic = {};
		try {
			randomMusic = manager.list(IConstants.SOUNDS_PATH + IConstants.RANDOM_MUSIC_PATH);
		} catch (IOException e) {
			DebugLog.e(TAG, " getRandomBgMusic ", e);
			return null;
		}

		if (randomMusic.length == 0) {
			DebugLog.e(TAG, "Random music list is empty, please check if folder in assets isn't empty.");
			return null;
		}

		int musicPosition = getRandomMusicIndex(randomMusic.length);
		String mediaFileName = IConstants.RANDOM_MUSIC_PATH + "/" + randomMusic[musicPosition];
		return createMusicFromAsset(mediaFileName);
	}

	public void playMenuClick() {
		if (menuClick != null) {
			menuClick.play();
		}
	}

	public void playCollision() {
		if (gameCollision != null) {
			gameCollision.play();
		}
	}

	public void playSpiritSaved() {
		if (spiritSaved != null) {
			spiritSaved.play();
		}
	}

	public void playSpiritDead() {
		if (spiritDead != null) {
			spiritDead.setVolume(1);
			spiritDead.play();
		}
	}

	public void playGameOver() {
		if (gameOver != null) {
			gameOver.play();
		}
	}

	public void playGameFinished() {
		if (gameFinished != null) {
			gameFinished.play();
		}
	}
	
	public void playLevelFinished() {
		if (levelFinished != null) {
			levelFinished.play();
		}
	}

	private Sound createSoundFromAsset(String stringName) {
		Sound sound = null;
		try {
			sound = SoundFactory.createSoundFromAsset(engine.getSoundManager(), context, stringName);
			sound.setVolume(soundVolume);
		} catch (final IOException e) {
			DebugLog.e(TAG, "Create sound from assets", e);
		}
		return sound;
	}

	private Music createMusicFromAsset(String stringName) {
		Music music = null;
		try {
			music = MusicFactory.createMusicFromAsset(engine.getMusicManager(), context, stringName);
			music.setVolume(musicVolume);
		} catch (final IOException e) {
			DebugLog.e(TAG, "Create music from assets", e);
		}
		return music;
	}

	public void playRandomBgMusic() {
		if (randomBgMusic == null) {
			randomBgMusic = getRandomBgMusic();
		}
		randomBgMusic.play();
		randomBgMusic.setOnCompletionListener(pOnCompletionListener);

		// For next track playing
		randomBgMusic = getRandomBgMusic();
	}

	private OnCompletionListener pOnCompletionListener = new OnCompletionListener() {

		@Override
		public void onCompletion(MediaPlayer mp) {
			playRandomBgMusic();
		}
	};

	public void pauseBackgoundMusic() {
		if (randomBgMusic != null)
			randomBgMusic.pause();
	}

	public void stopBackgoundMusic() {
		if (randomBgMusic != null)
			randomBgMusic.stop();
	}

	private int getRandomMusicIndex(int length) {
		int musicPosition = randomGenerator.nextInt(length);

		if (previousGeneratedPosition >= 0) {
			do {
				musicPosition = randomGenerator.nextInt(length);
			} while (musicPosition == previousGeneratedPosition);
		}

		previousGeneratedPosition = musicPosition;

		return musicPosition;
	}
}
